package edu.gmu.atelier;

/**
 * Field within a vector.
 * @author James H. Pope
 */
public interface Element extends Comparable
{
    //------------------------------------------------------------------------//
    // Mutator methods, for convenience and improved performance
    //------------------------------------------------------------------------//
    /**
     * Multiplies this element by another element, this element is modified.
     * @param b
     * @return this = this*b
     */
    public void multTo(Element b);
    
    /**
     * Adds this element by another element, this element is modified.
     * @param b
     * @return this = this+b
     */
    public void addTo(Element b);
    
    /**
     * Multiplies two specified parameters and adds result to this field.
     * @param x
     * @param v
     * @return this = this+v*x
     */
    public void multAddTo(Element x, Element v);
    
    //------------------------------------------------------------------------//
    // Non-mutator methods, immutable and analogous to mathematical functions
    //------------------------------------------------------------------------//
    /**
     * Multiplies this element by another element to produce a new element.
     * @param b
     * @return this*b
     */
    public Element mult(Element b);
    
    /**
     * Adds this element by another element to produce a new element.
     * @param b
     * @return this+b
     */
    public Element add(Element b);
    
    /**
     * Subtracts b from this element to produce a new element. 
     * @param b
     * @return this-b = this+b.negate()
     */
    public Element sub(Element b);
    
    /**
     * Returns a new copy of this object each time called.
     * @return new this
     */
    public Element copy();
    
    /**
     * Returns multiplicative inverse of the element.
     * @return this^(-1) such that this * this^(-1) = identity element
     */
    public Element inverse();
    
    /**
     * Returns square root of the element.
     * @return r such that r*r = this
     */
    public Element sqrt();
    
    /**
     * Returns the element raised to the specified power.
     * @return this^exp
     */
    public Element power(double exp);
    
    /**
     * Returns absolute value of the element.
     * @return
     */
    public Element abs();
    
    /**
     * Returns whether or not element is zero element (e+0=e, e*0=0).
     * @return true if this is zero element
     */
    public boolean isZero();
    
    /**
     * Returns whether or not element (real part) is less than zero.
     * @return true if this is a negative number
     */
    public boolean isNegative();
    
    /**
     * Returns negation of this element.
     * @return -this such that this + (-this) = zero element
     */
    public Element negate();
    
    /**
     * Returns closest interpretation to a real scalar.
     * @return 
     */
    public double doubleValue();
    
    /**
     * Determines whether or not specified element is similar within some given
     * tolerance defined by e.  The method does not imply any mathematical
     * properties.
     * <p>
     * If e is null then the method behaves as
     * the object equals method requiring exact equality.
     * @param obj
     * @param e
     * @return true if similar, false otherwise
     */
    public boolean similar( Object obj, Epsilon e );
    
    //------------------------------------------------------------------------//
    // Static accessor methods, does not affect instance of class
    //------------------------------------------------------------------------//
    /**
     * Gets the zero element such that c+(-c)=0 and c+0=0
     * @return zero
     */
    public Element getZero();
    
    /**
     * Gets the one element such that c*1=c
     * @return one
     */
    public Element getOne();
    
}
